import dayjs from 'dayjs'

// Parse the time to string
export const parseTime = (
  time?: object | string | number | null,
  cFormat?: string
): string | null => {
  if (time === undefined || !time) {
    return null
  }
  const format = cFormat || '{y}-{m}-{d} {h}:{i}:{s}'
  let date: Date
  if (typeof time === 'object') {
    date = time as Date
  } else {
    if (typeof time === 'string') {
      if (/^[0-9]+$/.test(time)) {
        // support "1548221490638"
        time = parseInt(time)
      } else {
        // support safari
        // https://stackoverflow.com/questions/4310953/invalid-date-in-safari
        time = time.replace(new RegExp(/-/gm), '/')
      }
    }
    if (typeof time === 'number' && time.toString().length === 10) {
      time = time * 1000
    }
    date = new Date(time)
  }
  const formatObj: { [key: string]: number } = {
    y: date.getFullYear(),
    m: date.getMonth() + 1,
    d: date.getDate(),
    h: date.getHours(),
    i: date.getMinutes(),
    s: date.getSeconds(),
    a: date.getDay()
  }
  const timeStr = format.replace(/{([ymdhisa])+}/g, (result, key) => {
    const value = formatObj[key]
    // Note: getDay() returns 0 on Sunday
    if (key === 'a') {
      return ['日', '一', '二', '三', '四', '五', '六'][value]
    }
    return value.toString().padStart(2, '0')
  })
  return timeStr
}

// Format and filter json data using filterKeys array
export const formatJson = (filterKeys: any, jsonData: any) =>
  jsonData.map((data: any) =>
    filterKeys.map((key: string) => {
      if (key === 'timestamp') {
        return parseTime(data[key])
      } else {
        return data[key]
      }
    })
  )

// Check if an element has a class
export const hasClass = (ele: HTMLElement, className: string) => {
  return !!ele.className.match(new RegExp('(\\s|^)' + className + '(\\s|$)'))
}

// Add class to element
export const addClass = (ele: HTMLElement, className: string) => {
  if (!hasClass(ele, className)) ele.className += ' ' + className
}

// Remove class from element
export const removeClass = (ele: HTMLElement, className: string) => {
  if (hasClass(ele, className)) {
    const reg = new RegExp('(\\s|^)' + className + '(\\s|$)')
    ele.className = ele.className.replace(reg, ' ')
  }
}

export function removeElementByClassNames(
  html: string,
  classNames: string[]
): string {
  const tmpElement = document.createElement('div')
  tmpElement.innerHTML = html
  classNames.forEach((className: string) => {
    const itemList:
      | HTMLCollectionOf<Element>
      | undefined = tmpElement?.getElementsByClassName(className)
    itemList &&
      Array.from(itemList).forEach((element: Element) => {
        element.parentNode && element.parentNode.removeChild(element)
      })
  })
  return tmpElement.innerHTML
}

// Toggle class for the selected element
export const toggleClass = (ele: HTMLElement, className: string) => {
  if (!ele || !className) {
    return
  }
  let classString = ele.className
  const nameIndex = classString.indexOf(className)
  if (nameIndex === -1) {
    classString += '' + className
  } else {
    classString =
      classString.substr(0, nameIndex) +
      classString.substr(nameIndex + className.length)
  }
  ele.className = classString
}

export function checkImgWidth(fileUrl: string) {
  return new Promise((resolve, reject) => {
    const img = new Image()
    let res = {}
    img.onload = function() {
      res = {
        width: (this as any).width,
        height: (this as any).height
      }
      resolve(res)
    }
    img.src = fileUrl
  })
}

export function openUrl(url: string) {
  window.open(url, '_blank')
}

export const exportExcel = (
  data: any,
  downloadFileName: any,
  param: any = {}
) => {
  const blob = new Blob(data, {
    type: 'application/vnd.ms-excel;charset=utf-8'
  })
  const downloadElement = document.createElement('a')
  const href = window.URL.createObjectURL(blob) // 创建下载的链接
  downloadElement.href = href
  downloadElement.download = downloadFileName + '.xls' // 下载后文件的名字
  document.body.appendChild(downloadElement)
  downloadElement.click() // 点击下载
  document.body.removeChild(downloadElement) // 下载完成移除元素
  window.URL.revokeObjectURL(href) // 释放blob对象
  param.cb && param.cb()
}

export function currentTime(date: any = new Date(), format = 'YYYYMMDDHHmmss') {
  return dayjs(date).format(format)
}

export const debounce = function(excute: Function, delay: number) {
  let timer: any
  return function(this: any, ...args: any) {
    if (timer) {
      clearTimeout(timer)
    }
    timer = setTimeout(() => {
      excute.apply(this, args)
    }, delay)
  }
}

export function getUrlParam(
  name: string,
  url: string = window.location.href
): string {
  const queryMap: Map<string, string> = new Map()
  if (url.split('?')[1] !== undefined && url.split('=')[1] !== undefined) {
    const query: string[] = url.split('?', 20)
    const validQuery: string = decodeURIComponent(query[query.length - 1])
    const params: string[] = validQuery.split('&')
    params.forEach((value: string) => {
      const map: string[] = value.split('=')
      queryMap.set(map[0], map[1])
    })
  }
  return queryMap.get(name) || ''
}

export const randomWord = function(randomFlag: any, min: any, max: any) {
  let str = ''
  let range = min
  const arr = [
    '0',
    '1',
    '2',
    '3',
    '4',
    '5',
    '6',
    '7',
    '8',
    '9',
    'a',
    'b',
    'c',
    'd',
    'e',
    'f',
    'g',
    'h',
    'i',
    'j',
    'k',
    'l',
    'm',
    'n',
    'o',
    'p',
    'q',
    'r',
    's',
    't',
    'u',
    'v',
    'w',
    'x',
    'y',
    'z',
    'A',
    'B',
    'C',
    'D',
    'E',
    'F',
    'G',
    'H',
    'I',
    'J',
    'K',
    'L',
    'M',
    'N',
    'O',
    'P',
    'Q',
    'R',
    'S',
    'T',
    'U',
    'V',
    'W',
    'X',
    'Y',
    'Z'
  ]

  // 随机产生
  if (randomFlag) {
    range = Math.round(Math.random() * (max - min)) + min
  }
  for (let i = 0; i < range; i++) {
    const pos = Math.round(Math.random() * (arr.length - 1))
    str += arr[pos]
  }
  return str
}

export const urlSateBase64Encode = (base64Str: any) => {
  if (!base64Str) return
  const safeStr = base64Str
    .replace(/\+/g, '-')
    .replace(/\//g, '_')
    .replace(/=/g, '')
  return safeStr
}

export default {
  getUrlParam
}
